import java.util.*;

public class ProcessScheduler {
    private List<Process> readyQueue = new ArrayList<>();
    private List<Process> blockedQueue = new ArrayList<>();
    private Process runningProcess = null;
    private int currentTime = 0;
    private int totalProcesses = 5;
    private int completedProcesses = 0;
    private String algorithm;
    private List<Process> allProcesses = new ArrayList<>();

    public ProcessScheduler(String algorithm) {
        this.algorithm = algorithm;
        initializeProcesses();
    }

    private void initializeProcesses() {
        Process p1 = new Process("P1", 0, 8, 3, 2);
        Process p2 = new Process("P2", 1, 4, 1, 3);
        Process p3 = new Process("P3", 2, 9, 4, 1);
        Process p4 = new Process("P4", 3, 5, 2, 4);
        Process p5 = new Process("P5", 4, 2, 5, 2);

        allProcesses.addAll(Arrays.asList(p1, p2, p3, p4, p5));

        for (Process p : allProcesses) {
            if (p.arrivalTime <= currentTime) {
                addToReadyQueue(p);
            }
        }
    }

    private void addToReadyQueue(Process process) {
        if (process.state != 1) {
            process.state = 0;
            readyQueue.add(process);
        }
    }

    private void addToBlockedQueue(Process process) {
        process.state = 2;
        blockedQueue.add(process);
    }

    private Process getNextProcess() {
        if (algorithm.equals("FCFS")) {
            return getFCFSProcess();
        } else if (algorithm.equals("SJF")) {
            return getSJFProcess();
        } else if (algorithm.equals("Priority")) {
            return getPriorityProcess();
        }
        return null;
    }

    private Process getFCFSProcess() {
        if (readyQueue.isEmpty()) return null;
        return readyQueue.get(0);
    }

    private Process getSJFProcess() {
        if (readyQueue.isEmpty()) return null;
        return Collections.min(readyQueue, Comparator.comparingInt(p -> p.remainingTime));
    }

    private Process getPriorityProcess() {
        if (readyQueue.isEmpty()) return null;
        return Collections.min(readyQueue, Comparator.comparingInt(p -> p.priority));
    }

    public void executeTimeSlice() {
        currentTime++;

        checkNewArrivals();
        handleBlockedProcesses();

        if (runningProcess == null) {
            selectNextProcess();
        }

        if (runningProcess != null) {
            runningProcess.remainingTime--;
            runningProcess.waitingTime++;

            if (runningProcess.remainingTime <= 0) {
                runningProcess.turnaroundTime = currentTime - runningProcess.arrivalTime;
                runningProcess.state = -1;
                runningProcess = null;
                completedProcesses++;
            }

            if (runningProcess != null && runningProcess.ioTime > 0 && Math.random() < 0.3) {
                runningProcess.ioLeft = runningProcess.ioTime;
                addToBlockedQueue(runningProcess);
                runningProcess = null;
            }
        }

        printStatus();

        if (completedProcesses == totalProcesses) {
            System.out.println("\n所有进程已完成！");
        }
    }

    private void checkNewArrivals() {
        for (Process p : allProcesses) {
            if (p.arrivalTime == currentTime) {
                addToReadyQueue(p);
            }
        }
    }

    private void handleBlockedProcesses() {
        Iterator<Process> iterator = blockedQueue.iterator();
        while (iterator.hasNext()) {
            Process p = iterator.next();
            p.ioLeft--;
            if (p.ioLeft <= 0) {
                iterator.remove();
                addToReadyQueue(p);
            }
        }
    }

    private void selectNextProcess() {
        Process nextProcess = getNextProcess();
        if (nextProcess != null) {
            runningProcess = nextProcess;
            runningProcess.state = 1;
            readyQueue.remove(runningProcess);
        }
    }

    private void printStatus() {
        System.out.println("\n时间: " + currentTime);

        if (runningProcess != null) {
            System.out.println("正在运行: " + runningProcess.name +
                    " (剩余时间: " + runningProcess.remainingTime + ")");
        } else {
            System.out.println("无进程正在运行");
        }

        System.out.print("就绪队列: ");
        if (readyQueue.isEmpty()) {
            System.out.print("空");
        } else {
            for (Process p : readyQueue) {
                System.out.print(p.name + "(" + p.remainingTime + ") ");
            }
        }

        System.out.print("\n阻塞队列: ");
        if (blockedQueue.isEmpty()) {
            System.out.print("空");
        } else {
            for (Process p : blockedQueue) {
                System.out.print(p.name + "(" + p.ioLeft + ") ");
            }
        }
    }

    public void printFinalResults() {
        System.out.println("\n调度算法: " + algorithm);
        System.out.println("完成的进程: " + completedProcesses + "/" + totalProcesses);

        for (Process p : allProcesses) {
            System.out.println(p.name + " 周转时间: " + p.turnaroundTime + ", 等待时间: " + p.waitingTime);
        }
    }

    public static void main(String[] args) {
        System.out.println("=== 进程调度模拟程序 ===");

        System.out.println("\n=== FCFS 调度算法 ===");
        ProcessScheduler fcfsScheduler = new ProcessScheduler("FCFS");
        while (fcfsScheduler.completedProcesses < 5) {
            fcfsScheduler.executeTimeSlice();
        }
        fcfsScheduler.printFinalResults();

        System.out.println("\n=== SJF 调度算法 ===");
        ProcessScheduler sjfScheduler = new ProcessScheduler("SJF");
        while (sjfScheduler.completedProcesses < 5) {
            sjfScheduler.executeTimeSlice();
        }
        sjfScheduler.printFinalResults();

        System.out.println("\n=== 优先级调度算法 ===");
        ProcessScheduler priorityScheduler = new ProcessScheduler("Priority");
        while (priorityScheduler.completedProcesses < 5) {
            priorityScheduler.executeTimeSlice();
        }
        priorityScheduler.printFinalResults();
    }
}